package com.twq.patternmatch.extractors

/**
 * Created by tangweiqun on 2017/11/22.
 */

object Extractors {
  def main(args: Array[String]): Unit = {
    //假设有一个邮箱字符串：laotang@qq.com
    //1、我们需要先判断它是不是一个邮箱，如果是邮箱的话，则打印邮箱的名字以及邮箱的域名，否则打印not an email address
    val emailStr: String = "laotang@qq.com"

    def isEmail(string: String) = string.split("@").length == 2

    def user(string: String) = string.split("@")(0)

    def domain(string: String) = string.split("@")(1)

    if (isEmail(emailStr)) println(user(emailStr) + " @ " + domain(emailStr)) else println("not an email address")

    //2、先有一个邮箱的seqs，我们需要检测该seqs的是否存在两个连续有效的邮箱的用户名相等
    val emailStrSeqs = List("laotang@qq.com", "laotang@qq.com", "laotang@163.com")
    val users = emailStrSeqs.map(user(_))
    val result = if (users.length >= 2) {
      users(0) == users(1)
    } else false
    println(result)

    //3、使用模式匹配来实现
    case class EMailCaseClass(user: String, domain: String)
    val parts = emailStr split "@"
    val eMailCaseClass = EMailCaseClass(parts(0), parts(1))

    eMailCaseClass match {
      case EMailCaseClass(user, domain) => println(user + " @ " + domain)
      case _ => println("not an email address")
    }

    val seqsClass = Seq(EMailCaseClass("laotang", "qq.com"), EMailCaseClass("laotang", "qq.com"), EMailCaseClass("laotang", "163.com"))
    seqsClass match {
      case EMailCaseClass(u1, d1) :: EMailCaseClass(u2, d2) :: _ if (u1 == u2) => true
      case _ => false
    }

    //4、上面的实现还是有点麻烦，如果我们想直接用string来匹配EMail呢？

    emailStr match {
      case EMail(user, domain) => println(user + " @ " + domain)
      case _ => println("not an email address")
    }


    emailStrSeqs match {
      case EMail(u1, d1) :: EMail(u2, d2) :: _ if (u1 == u2) => println("succ")
      case _ => println("not succ")
    }

    EMail("John", "epfl.ch")

  }


}

/**
 * 5、含有成员方法unapply的object，我们称之为extractors(萃取器)
 * extractors可以同时定义apply(可选的)和unapply方法
 */
object EMail {
  // The injection(注入) method (optional)
  // EMail("John", "epfl.ch") -> John@epfl.ch
  def apply(user: String, domain: String) = user + "@" + domain

  // The extraction(抽取) method (mandatory)
  //抽取方法的功能和apply的方法相反
  // unapply("John@epfl.ch") equals Some("John", "epfl.ch")
  // unapply("John Doe") equals None
  def unapply(str: String): Option[(String, String)] = {
    println("EMail unapply used")
    val parts = str split "@"
    if (parts.length == 2) Some(parts(0), parts(1)) else None
  }

  // 当遇到代码 selectorString match { case EMail(user, domain) => ... }的时候
  // 则会调用 EMail.unapply(selectorString)
}



